package cn.monkey.family.server.domain.shop.item.comment;

import cn.monkey.family.data.crud.repository.QueryDslQueryRequestRepository;
import cn.monkey.family.data.shop.item.comment.Comment;
import cn.monkey.family.data.shop.item.comment.CommentQueryRequest;
import cn.monkey.family.data.shop.item.comment.QComment;
import com.google.common.base.Strings;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.List;
import java.util.Optional;

@NoRepositoryBean
public interface CommentRepository extends QueryDslQueryRequestRepository<Comment, String, CommentQueryRequest> {
    @Override
    default Predicate queryDslPredicate(CommentQueryRequest queryRequest) {
        QComment comment = QComment.comment;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        String itemId = queryRequest.getItemId();
        if (!Strings.isNullOrEmpty(itemId)) {
            booleanBuilder.and(comment.itemId.eq(itemId));
        }
        String[] parentIds = queryRequest.getParentIds();
        if (parentIds != null) {
            booleanBuilder.and(comment.parentId.in(parentIds));
        }
        return booleanBuilder;
    }

    default Optional<Comment> findByParentId(@NonNull String parentId) {
        QComment comment = QComment.comment;
        return this.findOne(comment.parentId.eq(parentId));
    }

    default long findLastOffsetByItemIdAndParentId(@NonNull String itemId,
                                                   @Nullable String parentId) {
        QComment comment = QComment.comment;
        BooleanExpression expression = comment.itemId.eq(itemId);
        if (parentId != null) {
            expression = expression.and(comment.parentId.eq(parentId));
        }
        Sort sort = Sort.by(Sort.Direction.DESC, "offset");
        List<Comment> commentList = this.findAll(expression, sort);
        return commentList.stream().findFirst().map(Comment::getOffset).orElse(0L);
    }

    default List<Comment> findAllByItemIdAndParentIdIsNull(String itemId, Sort sort) {
        QComment comment = QComment.comment;
        return this.findAll(comment.itemId.eq(itemId).and(comment.parentId.isNull()), sort);
    }
}
